package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.face.AipFaceTemplate;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.autoconfig.sms.SmsTemplate;
import com.itheima.domain.db.Freeze;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import com.itheima.vo.ErrorResult;
import com.itheima.vo.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class UserManager {

    @DubboReference
    private UserService userService;

    @DubboReference
    private UserInfoService userInfoService;


    //保存用户
    public ResponseEntity save(User user) {
        Long id = userService.save(user);
        return ResponseEntity.ok(id);
    }

    public ResponseEntity findByPhone(String phone) {

        User user = userService.findByPhone(phone);

        return  ResponseEntity.ok(user);
    }


    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // 发送验证码
    public void smsSend(String phone) {
        //1生成6位验证码
        String code = RandomUtil.randomNumbers(6);
        code = "123456";
        //2.发送短信
        //smsTemplate.sendSms(phone, code);//todo 产品上线改回来
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone, code, Duration.ofMinutes(5));
    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //注册登录
    public ResponseEntity loginVerification(String phone, String verificationCode) {
        //1.从redis中取出我们之前设置的验证码
        String codeFromRedis = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        // 2.和用户输入的验证码作比较
        if (!StrUtil.equals(codeFromRedis, verificationCode)) {
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }
        //3，手机号比对，看看是不是老用户
        User user = userService.findByPhone(phone);
        Boolean isNew;
        String type;
        if (user != null) {//老用户
            isNew = false;
            type = "0101";
            //判断是不是被封禁的用户
            if ( stringRedisTemplate.hasKey("freeze_login_" + user.getId())) {
                return ResponseEntity.status(500).body(ErrorResult.loginFreezeError());
            }
            if (!stringRedisTemplate.hasKey("freeze_comment_" + user.getId()) && !stringRedisTemplate.hasKey("freeze_publish_" + user.getId())) {
                UserInfo userInfo = userInfoService.findById(user.getId());
                userInfo.setUserStatus("1");
                userInfoService.update(userInfo);
            }

        } else {//新用户
            isNew = true;
            type = "0102";
            user = new User();
            user.setMobile(phone);
            user.setPassword(ConstantUtil.INIT_PASSWORD);
            Long userId = userService.save(user);
            user.setId(userId);
            //向环信注册新用户
            huanXinTemplate.register("HX" + userId);
        }
        //4.jwt制作令牌
        user.setPassword(null);
        Map<String, Object> claims = BeanUtil.beanToMap(user);
        String token = JwtUtil.createToken(claims);
        //5.向redis存储
        String json = JSON.toJSONString(user);
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));
        //6.删除redis中验证码
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE + phone);
        //-----------------
        //封装log对象
        Log log = new Log();
        log.setUserId(user.getId());//用户id
        log.setType(type);//  类型
        log.setLogTime(DateUtil.formatDate(new Date()));// 操作时间  2022-2-24
        log.setPlace("北京顺义黑马程序员");
        log.setEquipment("华为Mate40Pro");
        //发送mq消息
        rabbitTemplate.convertAndSend("tanhua.log", log);
        //------------------------------
        //7.封装结果返回
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("isNew", isNew);
        map.put("userId", user.getId());
        return ResponseEntity.ok(map);
    }



    public void loginReginfo(UserInfo userInfo, String token) {
        User user = findUserByToken(token);
        //user里的id跟userinfo的id一样
        userInfo.setId(user.getId());
        //调用rpc保存
        userInfoService.save(userInfo);

    }
    //解析token获取user
    public User findUserByToken(String token) {
        //判断是否登录
        Boolean isLogin = stringRedisTemplate.hasKey(ConstantUtil.USER_TOKEN + token);
        if (isLogin) {
            String json = stringRedisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);
            User user = JSON.parseObject(json, User.class);
            stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));
            return user;
        } else {
            return null;
        }

    }

    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    public ResponseEntity loginReginfoHead(MultipartFile headPhoto, String token) throws IOException {
       //1.人脸检测
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        //非人脸
        if (detect == false) {
            return ResponseEntity.status(500).body(ErrorResult.faceError());
        }
        //调用阿里云oss存储图片
        String url = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        User user = findUserByToken(token);
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setAvatar(url);
        userInfo.setCoverPic(url);
        //调用rpc更新
        userInfoService.update(userInfo);

        return ResponseEntity.ok(null);
    }

    public ResponseEntity findUserInfoVo(Long id) {
        UserInfo userinfo = userInfoService.findById(id);
        //封装vo
        UserInfoVo vo = new UserInfoVo();
        BeanUtil.copyProperties(userinfo, vo);

        return ResponseEntity.ok(vo);
    }

    public void putUserInfo(UserInfo userInfo) {

        userInfoService.update(userInfo);
    }


    //校验
    public ResponseEntity verificationCode(String verificationCode) {

        String code = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE+UserHolder.get().getMobile());

        Boolean verification;
        if (StrUtil.equals(code, verificationCode)) {

            verification = true;
            stringRedisTemplate.delete(ConstantUtil.SMS_CODE);

        } else {
            verification = false;

        }

        Map<String, Object> map1= new HashMap<>();
        map1.put("verification", verification);
        return ResponseEntity.ok(map1);
    }

    //修改手机号
    public ResponseEntity  updatephone(String phone, String tonken) {



        if (StrUtil.equals(phone, UserHolder.get().getMobile())) {

            return ResponseEntity.status(200).body("修改的手机号不能和现在的一样");
        }
        User user = new User();

        user.setMobile(phone);
        int update = userService.update(user,UserHolder.get().getId());

        //删除tonken
        stringRedisTemplate.delete(ConstantUtil.USER_TOKEN +tonken);
        if (update == 0) {
            return ResponseEntity.status(200).body(ErrorResult.error());
        } else if (update>0){


        }

        return ResponseEntity.ok(null);

    }
}
